package com.demo.study.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 创建线程的4种模式
 *
 * @author Baymax
 * @since 2021/8/21
 */
public class T01_CreateThread {
}

/**
 * 方式一：继承于Thread类
 */
class Thread1 extends Thread {
    public static void main(String[] args) {
        new Thread1().start();
    }

    @Override
    public void run() {
        System.out.println("Thread1 run ...");
    }
}

/**
 * 方式二：实现Runnable接口
 */
class Thread2 implements Runnable {
    public static void main(String[] args) {
        new Thread(new Thread2()).start();
    }

    @Override
    public void run() {
        System.out.println("Thread2 run ...");
    }
}

/**
 * 方式三：实现Callable接口
 * 通过实现Callable接口的方式，创建FutureTask，传递给Thread的构造器中进行调用，可以获取异步线程的返回值
 */
class Thread3 {
    private static int num;

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 1.直接创建一个实现类
        Thread3_T thread3 = new Thread3_T();
        FutureTask<Integer> futureTask = new FutureTask<>(thread3);
        Thread thread = new Thread(futureTask);
        thread.start();
        System.out.println(futureTask.get());

        System.out.println("------------------------------------------------");

        // 2.实现匿名内部类的方式实现-lambda表达式
        FutureTask<Integer> futureTask2 = new FutureTask<>(() -> {
            num++;
            System.out.println("futureTask2 call ...");
            return num;
        });
        Thread thread2 = new Thread(futureTask2);
        thread2.start();
        System.out.println(futureTask2.get());
    }

    static class Thread3_T implements Callable<Integer> {
        @Override
        public Integer call() {
            num++;
            System.out.println("Thread3_T call ...");
            return num;
        }
    }
}

/**
 * 方式四：使用线程池<p>
 * 核心参数：
 * <li>corePoolSize：核心池的大小
 * <li>maximumPoolSize：最大线程数
 * <li>keepAliveTime：线程没有任务时最多保持多长时间后会终止
 * <p>
 * 线程池正真的实现类：ThreadPoolExecutor
 */
class Thread4 {
    public static void main(String[] args) throws InterruptedException {
        // 可缓存线程池
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        cachedThreadPool.execute(() -> System.out.println("Thread_4 cachedThreadPool execute ..."));
        cachedThreadPool.shutdown();

        // 定长线程池
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
        fixedThreadPool.execute(() -> System.out.println("Thread_4 fixedThreadPool execute ..."));
        fixedThreadPool.shutdown();

        // 定时线程池（定时执行）
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
        AtomicInteger start = new AtomicInteger();
        Runnable task = new Runnable() {
            @Override
            public void run() {
                String name = Thread.currentThread().getName();
                start.getAndIncrement(); // 原子性自加
                System.out.println("scheduledExecutorService execute, threadName: " + name + ", num: " + start.get());
            }
        };
        // 定时任务，延迟0秒，每秒执行一次
        scheduledExecutorService.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);
        Thread.sleep(30 * 1000);
        scheduledExecutorService.shutdown();

        // 单线程化线程池
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        singleThreadExecutor.execute(() -> {
            String name = Thread.currentThread().getName();
            System.out.println("singleThreadExecutor execute, threadName: " + name);
        });
    }
}
